/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fasea.model;

import fasea.constants.Constants;
import fasea.index.Indexer;
import fasea.index.IndexerStatusListener;
import fasea.index.IndexerThreadExcecutor;
import fasea.search.SearchResults;
import fasea.search.Searcher;
import fasea.utils.FileUtil;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author lars-wolfram
 */
public class FaseaModel extends Observable{

    private IndexerThreadExcecutor indexer;
    private IndexProperties indexProperties;
    private Searcher searcher;
    private SearchResults searchResults;
    private String indexerInfoText = "";

    public void performSearch(String userInput) {
        if (searcher == null) {
            if( indexer != null && indexer.isRunning()){
                searcher = new Searcher(indexer.getIndexWriter());
            }else{
                searcher = new Searcher(this.indexProperties.getIndexFolder());
            }
        }
        try {
            searchResults = searcher.search(userInput);
        } catch (Exception ex) {
            //Logger.getLogger(FaseaModel.class.getName()).log(Level.SEVERE, null, ex);
            searchResults = new SearchResults();
        }
        notifyObservers(Action.SEARCH_FINISHED);
    }
    
    private void notifyObservers(Action action){
        super.setChanged(); 
        super.notifyObservers(action);
    }

    public void startIndexing() {
        try {
            if (indexer == null) {
                createIndexer();
            }
            indexer.startIndexing(indexProperties.getIndexFolder(),indexProperties.getIndexingFolders());
            
        } catch (IOException ex) {
            Logger.getLogger(FaseaModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void createIndexer() {
        indexer = new IndexerThreadExcecutor();
        indexer.setIndexerStatusListener(new IndexerStatusListener() {

            public void indexerStarted() {
                searcher = null;
                FaseaModel.this.notifyObservers(Action.INDEXER_STARTED);
            }

            public void indexerFinished() {
                searcher = null;
                indexProperties.setLastIndexed(System.currentTimeMillis());
                saveIndexProperties();
                FaseaModel.this.notifyObservers(Action.INDEXER_FINISHED);
            }

            public void write(String info) {
                indexerInfoText = info;
                FaseaModel.this.notifyObservers(Action.INDEXER_INFOTEXT_CHANGED);
            }

            public void indexerAborted() {
                searcher = null;
                FaseaModel.this.notifyObservers(Action.INDEXER_ABORTED);
            }

            public void setIndexDocumentsCount(int count) {
                indexProperties.setIndexedDocumentsCount(count);
                FaseaModel.this.notifyObservers(Action.INDEXER_DOCUMENTSCOUNT_CHANGED);
            }
        });
    }
    
    public void abortIndexing() {
        indexer.abortIndexing();
    }

    public void init() {
        indexProperties = loadProperties();
        if (indexProperties.isOldVersion()) {
            update();
        }

        // pop-up window!
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                try {
                    /*
                     * searchFrame = new SearchFrame();
                     * searchFrame.setVisible(true);
                     */
                    notifyObservers(Action.SHOW_SEARCHVIEW);
                    if (!Indexer.indexExists(FaseaModel.this.indexProperties.getIndexFolder())) {
                        notifyObservers(Action.SHOW_PROPERTIESVIEW);
                    }
                } catch (IOException ex) {
                    Logger.getLogger(FaseaModel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    private static IndexProperties loadProperties() {
        File propsFile = new File(Constants.getApplicationPropertiesFilePath());
        IndexProperties props = new IndexProperties(propsFile);
        return props;
    }

    private static void update() {
        //TODO:Updater implementieren
    }

    public void setProperties(IndexProperties properties) {
        indexProperties = properties;
    }
    
    public long getLastIndexed() {
        return indexProperties.getLastIndexed();
    }

    public void setIndexingFolders(IndexingFolderList indexingFolders) {
        indexProperties.removeAllIndexingFolders();
        for(IndexingFolder indexingFolder : indexingFolders){
            if (indexingFolder.getIndexingFolder().exists() && FileUtil.isDirectory(indexingFolder.getIndexingFolder())) {
                indexProperties.addIndexingFolder(indexingFolder);
            }
        }
    }
    
    public void saveIndexProperties(){
        indexProperties.save();
    }
    
    public File getIndexFolder() {
        return indexProperties.getIndexFolder();
    }

    public IndexingFolderList getIndexingFolders() {
        return indexProperties.getIndexingFolders();
    }
    
    public int getIndexerDocumentsCount() {
        return indexProperties.getIndexedDocumentsCount();
    }

    public SearchResults getSearchResults() {
        return searchResults;
    }
    
    public void openFileInSearchResult(int index){
        try {
            File file = new File(searchResults.getDocument(index).getPath());
            Desktop.getDesktop().open(file);
        } catch (IOException ex) {
            Logger.getLogger(FaseaModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public String getIndexerInfoText(){
        return indexerInfoText;
    }

    public void showPropertiesViewButtonClicked() {
        notifyObservers(Action.SHOW_PROPERTIESVIEW);
    }
}
